import logging
from rich.logging import RichHandler
from logging import StreamHandler
import os
from datetime import datetime


class Logger:
    """
    日志工具类（单例模式）
    提供类方法直接调用，支持动态修改日志级别
    """
    # 单例实例存储
    _instance = None

    # 日志配置参数（类级别的配置，可根据需求修改）
    LOG_DIR = "logs"
    LOG_FILE_NAME = f"app_{datetime.now().strftime('%Y%m%d')}.log"  # 按日生成日志文件
    LOG_FILE_PATH = os.path.join(LOG_DIR, LOG_FILE_NAME)
    CONSOLE_LEVEL = logging.INFO  # 控制台日志级别
    FILE_LEVEL = logging.INFO     # 文件日志级别

    # 存储处理器引用（用于动态修改级别）
    _console_handler = None
    _file_handler = None


    def __new__(cls, *args, **kwargs):
        """单例模式实现：确保全局只有一个Logger实例"""
        if not cls._instance:
            cls._instance = super().__new__(cls)
            # 初始化日志配置（仅首次创建实例时执行）
            cls._instance._init_logger()
        return cls._instance


    def _init_logger(self):
        """初始化日志配置（私有方法，仅内部调用）"""
        # 创建日志目录
        os.makedirs(self.LOG_DIR, exist_ok=True)

        # 获取根日志对象
        self.root_logger = logging.getLogger()
        self.root_logger.setLevel(logging.DEBUG)  # 全局最低级别
        self.root_logger.handlers.clear()         # 清除默认处理器

        # 配置控制台处理器（保存引用用于后续修改级别）
        self._setup_console_handler()
        # 配置文件处理器（保存引用用于后续修改级别）
        self._setup_file_handler()


    def _setup_console_handler(self):
        """配置控制台处理器（私有方法，仅内部调用）"""
        self._console_handler = StreamHandler(
            
        )
        self._console_handler.setLevel(self.CONSOLE_LEVEL)
        # 控制台日志格式：包含模块和行号
        console_formatter = logging.Formatter(
            "%(asctime)s - %(levelname)s - %(module)s:%(lineno)d - %(message)s"
        )
        self._console_handler.setFormatter(console_formatter)
        self.root_logger.addHandler(self._console_handler)


    def _setup_file_handler(self):
        """配置文件处理器（私有方法，仅内部调用）"""
        self._file_handler = logging.FileHandler(
            filename=self.LOG_FILE_PATH,
            mode="a",
            encoding="utf-8"
        )
        self._file_handler.setLevel(self.FILE_LEVEL)
        # 文件日志格式：包含完整信息
        file_formatter = logging.Formatter(
            "%(asctime)s - %(levelname)s - %(module)s:%(lineno)d - %(message)s"
        )
        self._file_handler.setFormatter(file_formatter)
        self.root_logger.addHandler(self._file_handler)


    # -------------------------- 日志输出类方法 --------------------------
    @classmethod
    def debug(cls, message):
        """类方法：输出DEBUG级日志"""
        if not cls._instance:
            cls()
        cls._instance.root_logger.debug(f"📝 {message}",stacklevel=2)


    @classmethod
    def info(cls, message):
        """类方法：输出INFO级日志"""
        if not cls._instance:
            cls()
        cls._instance.root_logger.info(f"ℹ️ {message}",stacklevel=2)


    @classmethod
    def warning(cls, message):
        """类方法：输出WARNING级日志"""
        if not cls._instance:
            cls()
        cls._instance.root_logger.warning(f"⚠️ {message}",stacklevel=2)


    @classmethod
    def error(cls, message, exc_info=False):
        """类方法：输出ERROR级日志"""
        if not cls._instance:
            cls()
        cls._instance.root_logger.error(f"❌ {message}",stacklevel=2, exc_info=exc_info)


    @classmethod
    def critical(cls, message, exc_info=False):
        """类方法：输出CRITICAL级日志"""
        if not cls._instance:
            cls()
        cls._instance.root_logger.critical(f"💥 {message}",stacklevel=2, exc_info=exc_info)


    # -------------------------- 日志级别修改类方法 --------------------------
    @classmethod
    def set_console_level(cls, level):
        """
        动态修改控制台日志级别
        :param level: 日志级别（如 logging.INFO, logging.WARNING 等）
        """
        if not cls._instance:
            cls()
        # 验证级别有效性
        if level not in [logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL]:
            raise ValueError("无效的日志级别，请使用 logging 模块定义的级别（如 logging.INFO）")
        cls._instance._console_handler.setLevel(level)
        cls.info(f"控制台日志级别已修改为: {logging.getLevelName(level)}")


    @classmethod
    def set_file_level(cls, level):
        """
        动态修改文件日志级别
        :param level: 日志级别（如 logging.INFO, logging.WARNING 等）
        """
        if not cls._instance:
            cls()
        if level not in [logging.DEBUG, logging.INFO, logging.WARNING, logging.ERROR, logging.CRITICAL]:
            raise ValueError("无效的日志级别，请使用 logging 模块定义的级别（如 logging.INFO）")
        cls._instance._file_handler.setLevel(level)
        cls.info(f"文件日志级别已修改为: {logging.getLevelName(level)}")


    @classmethod
    def get_current_levels(cls):
        """获取当前控制台和文件的日志级别"""
        if not cls._instance:
            cls()
        console_level = logging.getLevelName(cls._instance._console_handler.level)
        file_level = logging.getLevelName(cls._instance._file_handler.level)
        return {
            "console_level": console_level,
            "file_level": file_level
        }